package com.twu.biblioteca.commandexecutor.subexecutors;

import com.twu.biblioteca.commandexecutor.BibliotecaCommandExecutor_SubModules;
import com.twu.biblioteca.commandexecutor.ProgramExitRequestedException;
import com.twu.biblioteca.librarycollection.LibraryCollection;
import com.twu.biblioteca.memberdata.MemberData;
import com.twu.biblioteca.memberdata.UserDetails;

class NoBookInCommandException extends Exception
{
    public NoBookInCommandException(String command)
    {
        super("No book in command '" + command + "'");
    }
}

public class ReserveBookSubExecutor implements BibliotecaCommandExecutor_SubModules.SubExecutor
    {
        int menuPos = -1;

        public static final String succesfulCheckout = "Thank You! Enjoy the book.";
        public static final String unsuccesfulCheckout = "Sorry we don't have that book yet.";
        public static final String forgotBookInReserveBookMessage
                = "Please specify a book when using the reserve book command (e.g: 2 BookA)";
        public static final String notLoggedInMessage = "Please log in before reserving a book.";

        public ReserveBookSubExecutor(int menuPos)
        {
            this.menuPos = menuPos;
        }

        public String getMenuOptionText()
        {
            return menuPos + " Book";
        }

        public String getMenuOptionDescription()
        {
            return "Reserve Book";
        }

        public boolean canExecute(String command)
        {
            if(command.startsWith(menuPos + ""))
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        public String execute(LibraryCollection libraryColl, MemberData memberData, UserDetails userDetails, String command) throws ProgramExitRequestedException
        {
            if(!loginCheck(userDetails))
            {
                return notLoggedInMessage;
            }
            return reserveBook(libraryColl, command);
        }

        @Override
        public boolean isDone() {
            return true;
        }

        @Override
        public void reset() {
            //Do nothing; we have no state
        }

        private boolean loginCheck(UserDetails userDetails)
        {
            return userDetails.isLoggedIn();
        }

        private String reserveBook(LibraryCollection libraryColl, String command)
        {
            try
            {
                String book = retrieveBookFromCommand(command);
                return checkoutBook(libraryColl, book) + "\n";
            }
            catch(NoBookInCommandException nbice)
            {
                return forgotBookInReserveBookMessage + "\n";
            }
        }

        private String checkoutBook(LibraryCollection libraryColl, String book)
        {
            if(libraryColl.isBookAvailable(book))
            {
                return succesfulCheckout;
            }
            else
            {
                return unsuccesfulCheckout;
            }
        }

        private String retrieveBookFromCommand(String command) throws NoBookInCommandException
        {
            if(commandContainsProperBook(command))
            {
                return command.substring(2, command.length()).trim();
            }
            else
            {
                throw new NoBookInCommandException(command);
            }
        }

        private boolean commandContainsProperBook(String command)
        {
            if(commandLongEnough(command) && checkCommandContainsBook(command))
                return true;
            else
                return false;
        }

        private boolean commandLongEnough(String command)
        {
            return command.length() > 2;
        }

        private boolean checkCommandContainsBook(String command)
        {
            String bookSubstring = command.substring(2, command.length()).trim();
            return !bookSubstring.equals("");
        }

}
